package mil.nga.giat.mage.map.marker;
import android.animation.ArgbEvaluator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.os.Build;
import android.util.Log;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import java.io.IOException;
import mil.nga.giat.mage.sdk.datastore.location.Location;
import mil.nga.giat.mage.sdk.datastore.user.User;
public class LocationBitmapFactory {
private static Long upperBoundTimeInSeconds = 1800L;
private static final String LOG_NAME = LocationBitmapFactory.class.getName();
// TODO : SCOTT UFM
private static final Integer[] colorGradient = { 0xff0000ff, 0xffffff00 ,0xffffa500 };
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static Bitmap bitmap(Context context, Location location, User user) {
Bitmap bitmap = createDot(context, location, user);
Log.d(LOG_NAME, "Drawing the bitmap for user " + user.getDisplayName());
final String iconPath = user.getUserLocal().getLocalIconPath();
if (iconPath != null) {
Bitmap userIcon = bitmapUser(context, iconPath);
if (userIcon != null) {
bitmap = combineIconAndDot(bitmap.copy(Bitmap.Config.ARGB_8888, true), userIcon);
}
}
return bitmap;
}
private static Bitmap combineIconAndDot(Bitmap dot, Bitmap icon) {
Integer width = Math.max(dot.getWidth(), icon.getWidth());
Integer height = (dot.getHeight() / 2) + icon.getHeight();
Bitmap combined = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas c = new Canvas(combined);
c.drawBitmap(dot, (width-dot.getWidth())/2, height - dot.getHeight(), null);
c.drawBitmap(icon, (width-icon.getWidth())/2, 0, null);
return combined;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static Bitmap bitmapUser(Context context, String iconPath) {
Bitmap bitmap = BitmapFactory.decodeFile(iconPath);
if (bitmap == null) {
return null;
}
Integer maxDimension = Math.max(bitmap.getWidth(), bitmap.getHeight());
float density = context.getResources().getDisplayMetrics().xdpi;
double scale = (density/3.5) / maxDimension;
int outWidth = Double.valueOf(scale*Integer.valueOf(bitmap.getWidth()).doubleValue()).intValue();
int outHeight = Double.valueOf(scale*Integer.valueOf(bitmap.getHeight()).doubleValue()).intValue();
bitmap = Bitmap.createScaledBitmap(bitmap, outWidth, outHeight, true);
return bitmap;
}
public static BitmapDescriptor bitmapDescriptor(Context context, Location location, User user) {
Bitmap bitmap = bitmap(context, location, user);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
public static BitmapDescriptor dotBitmapDescriptor(Context context, Location location, User user) {
Bitmap bitmap = createDot(context, location, user);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
public static Bitmap createDot(Context context, Location location, User user) {
Bitmap dotBitmap = null;
try {
Long interval = (System.currentTimeMillis() - location.getTimestamp().getTime()) / 1000l;
// max out at 30 minutes
interval = Math.min(interval, upperBoundTimeInSeconds);
// upper bound in minutes
Double u = upperBoundTimeInSeconds.doubleValue() / 60.0;
// non-linear lookup
// 0 mins = blue
// 10 mins = yellow
// 30 mins = orange
Double gradientIndexDecimalNormalized = -0.25 + Math.sqrt((u * u) + (u * 24 * (interval.doubleValue() / 60.0))) / (4 * u);
// between 0 and 1
gradientIndexDecimalNormalized = Math.min(Math.max(0.0, gradientIndexDecimalNormalized), 1.0);
// find the index into the gradient
int gradientIndex = (int) (gradientIndexDecimalNormalized * (double) (colorGradient.length - 1));
// linearly interpolate between the gradient index
Integer COLOR1 = colorGradient[gradientIndex];
Integer COLOR2 = colorGradient[Math.min(gradientIndex + 1, colorGradient.length - 1)];
// TODO : this use to use a gradient, but no longer do. Could remove some of this code
int color = (Integer) new ArgbEvaluator().evaluate(gradientIndexDecimalNormalized.floatValue(), COLOR1, COLOR1);
// use a invert filter to swap black and white colors in the bitmap. This will preserve the original black
float[] colorMatrix_Negative = { -1.0f, 0, 0, 0, 255, 0, -1.0f, 0, 0, 255, 0, 0, -1.0f, 0, 255, 0, 0, 0, 1.0f, 0 };
// make a mutable copy of the bitmap
Bitmap bitmapFile = BitmapFactory.decodeStream(context.getAssets().open("dots/black_dot.png"));
// scale the image to a good size
Integer maxDimension = Math.max(bitmapFile.getWidth(), bitmapFile.getHeight());
float density = context.getResources().getDisplayMetrics().xdpi; //context.getResources().getDisplayMetrics().densityDpi;
double scale = (density/10.0) / maxDimension;
int outWidth = Double.valueOf(scale*Integer.valueOf(bitmapFile.getWidth()).doubleValue()).intValue();
int outHeight = Double.valueOf(scale*Integer.valueOf(bitmapFile.getHeight()).doubleValue()).intValue();
bitmapFile = Bitmap.createScaledBitmap(bitmapFile, outWidth, outHeight, true);
dotBitmap = bitmapFile.copy(Bitmap.Config.ARGB_8888, true);
Canvas myCanvas = new Canvas(dotBitmap);
// invert the gradient first
Paint gradientPaint = new Paint();
gradientPaint.setColorFilter(new LightingColorFilter(Color.WHITE, 0xFFFFFFFF - color));
myCanvas.drawBitmap(dotBitmap, 0, 0, gradientPaint);
// invert the entire image second
Paint negativePaint = new Paint();
negativePaint.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(colorMatrix_Negative)));
myCanvas.drawBitmap(dotBitmap, 0, 0, negativePaint);
} catch (IOException e1) {
try {
dotBitmap = BitmapFactory.decodeStream(context.getAssets().open("dots/maps_dav_bw_dot.png"));
// scale the image to a good size
Integer maxDimension = Math.max(dotBitmap.getWidth(), dotBitmap.getHeight());
float density = context.getResources().getDisplayMetrics().xdpi; //context.getResources().getDisplayMetrics().densityDpi;
double scale = (density/3.5) / maxDimension;
int outWidth = Double.valueOf(scale*Integer.valueOf(dotBitmap.getWidth()).doubleValue()).intValue();
int outHeight = Double.valueOf(scale*Integer.valueOf(dotBitmap.getHeight()).doubleValue()).intValue();
dotBitmap = Bitmap.createScaledBitmap(dotBitmap, outWidth, outHeight, true);
} catch (IOException e2) {
Log.e(LOG_NAME, "Problem setting generating bitmap", e2);
}
}
return dotBitmap;
}
}